home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / pluginy Firefox / 3006 / 3006.xpi / components / dhYoutubeProbe.js < prev    next >
Text File  |  2010-01-15  |  10KB  |  273 lines

  1. /******************************************************************************
  2.  *            Copyright (c) 2006-2009 Michel Gutierrez. All Rights Reserved.
  3.  ******************************************************************************/
  4.  
  5. /**
  6.  * Constants.
  7.  */
  8.  
  9. const NS_YTPROBE_CID = Components.ID("{506124c4-0076-48d2-bfee-14bb3187560e}");
  10. const NS_YTPROBE_PROG_ID = "@downloadhelper.net/youtube-probe;1";
  11. const DHNS = "http://downloadhelper.net/1.0#";
  12.  
  13. var Util=null;
  14.  
  15. /**
  16. * Object constructor
  17. */
  18. function YTProbe() {
  19.     try {
  20.         //dump("[YTProbe] constructor\n");
  21.         var prefService=Components.classes["@mozilla.org/preferences-service;1"]
  22.                                            .getService(Components.interfaces.nsIPrefService);
  23.         this.pref=prefService.getBranch("dwhelper.");
  24.         this.core=Components.classes["@downloadhelper.net/core;1"].
  25.             getService(Components.interfaces.dhICore);
  26.         this.core.registerProbe(this);
  27.     } catch(e) {
  28.         dump("[YTProbe] !!! constructor: "+e+"\n");
  29.     }
  30. }
  31.  
  32. YTProbe.prototype = {}
  33.  
  34. YTProbe.prototype.handleDocument=function(document,window) {
  35.     try {
  36.         //dump("[YTProbe] handleDocument("+document.URL+")\n");
  37.         if(/^http:\/\/[^\/]*\.?youtube\.[^\/\.]+/.test(document.URL)) {
  38.             var dom=document.documentElement;
  39.             var scripts=Util.xpGetStrings(dom,".//script/text()",{});
  40.             var videoId=null;
  41.             var t=null;
  42.             for(var i=0;i<scripts.length;i++) {
  43.                 var script=scripts[i];
  44.                 var match=/\"video_id\": \"(.*?)\".*\"t(?:oken)?\": \"(.*?)\"/m.exec(script);
  45.                 if(match!=null && match.length==3) {
  46.                     videoId=match[1];
  47.                     t=match[2];
  48.                     break;
  49.                 }
  50.                 var match=/\"t(?:oken)?\": \"(.*?)\".*\"video_id\": \"(.*?)\"/m.exec(script);
  51.                 if(match!=null && match.length==3) {
  52.                     videoId=match[2];
  53.                     t=match[1];
  54.                     break;
  55.                 }
  56.             }
  57.             if(videoId==null || t==null) {
  58.                 for(var i=0;i<scripts.length;i++) {
  59.                     var script=scripts[i];
  60.                     var match=/video_id=([^&]+)(?:&.*)&t=([^&]+)/m.exec(script);
  61.                     if(match!=null && match.length==3) {
  62.                         videoId=match[1];
  63.                         t=match[2];
  64.                         break;
  65.                     }
  66.                     var match=/[&\?]t=(.*?)&.*video_id=(.*?)(?:&|")/m.exec(script);
  67.                     if(match!=null && match.length==3) {
  68.                         videoId=match[2];
  69.                         t=match[1];
  70.                         break;
  71.                     }
  72.                 }
  73.             }
  74.             if(videoId==null || t==null) {
  75.                 var embeds=Util.xpGetStrings(dom,".//embed/@src",{});
  76.                 for(var i=0;i<embeds.length;i++) {
  77.                     var embed=embeds[i];
  78.                     var match=/video_id=(.*?)&.*t=(.*?)(?:&|")/m.exec(embed);
  79.                     if(match!=null && match.length==3) {
  80.                         videoId=match[1];
  81.                         t=match[2];
  82.                         break;
  83.                     }
  84.                 }
  85.                 if(videoId==null || t==null) {
  86.                     return;
  87.                 }
  88.             }
  89.             var title=Util.xpGetString(dom,"/html/head/meta[@name='title']/@content");
  90.             if(title==null || title.length==0) {
  91.                 title=Util.xpGetString(dom,".//h3[@id='playnav-restricted-title']/text()");
  92.                 if(title)
  93.                     title=title.replace(/"/g,"");
  94.             }
  95.             var url="http://www.youtube.com/get_video?video_id="+videoId+"&t="+t;
  96.  
  97.             var fileName=title;
  98.             var unmodifiedFilename=false;
  99.             try {
  100.                 unmodifiedFilename=this.pref.getBoolPref("yt-unmodified-filename");        
  101.             } catch(e) {}
  102.             fileName=fileName.replace(/[\/"\?\*:\|"'\\]/g,"_");
  103.             if(unmodifiedFilename==false) {
  104.                 var keepSpaces=false;
  105.                 try {
  106.                     keepSpaces=this.pref.getBoolPref("yt-keep-spaces");
  107.                 } catch(e) {}
  108.                 if(keepSpaces)
  109.                     fileName=fileName.replace(/[^a-zA-Z0-9\.\- ]/g,"_");
  110.                 else
  111.                     fileName=fileName.replace(/[^a-zA-Z0-9\.\-]/g,"_");
  112.             }
  113.             
  114.             var checkHQ=this.pref.getBoolPref("yt-check-hq");
  115.             if(checkHQ) {
  116.                 var desc=Components.classes["@mozilla.org/properties;1"].
  117.                     createInstance(Components.interfaces.nsIProperties);
  118.                 var checker=Components.classes["@downloadhelper.net/ythq-checker;1"].
  119.                     createInstance(Components.interfaces.dhIYTHQChecker);
  120.                 desc.set("window",window);
  121.                 desc.set("document",document);
  122.                 Util.setPropsString(desc,"page-url",document.URL);
  123.                 Util.setPropsString(desc,"youtube-title",title);
  124.                 Util.setPropsString(desc,"label",Util.getText("label.high-quality-prefix")+" "+title);
  125.                 Util.setPropsString(desc,"base-name",fileName);
  126.                 Util.setPropsString(desc,"file-name",fileName);
  127.                 Util.setPropsString(desc,"icon-url","http://www.youtube.com/favicon.ico");
  128.                 checker.checkMulti(url,this,desc);
  129.             }
  130.             
  131.             var desc=Components.classes["@mozilla.org/properties;1"].
  132.                 createInstance(Components.interfaces.nsIProperties);
  133.             Util.setPropsString(desc,"media-url",url);
  134.             Util.setPropsString(desc,"page-url",document.URL);
  135.             Util.setPropsString(desc,"label",title);
  136.             Util.setPropsString(desc,"base-name",fileName);
  137.             Util.setPropsString(desc,"file-name",fileName+".flv");
  138.             Util.setPropsString(desc,"file-extension","flv");
  139.             Util.setPropsString(desc,"capture-method","youtube");
  140.             Util.setPropsString(desc,"icon-url","http://www.youtube.com/favicon.ico");
  141.             this.core.addEntryForDocument(desc,document,window);
  142.         } 
  143.     } catch(e) {
  144.         dump("!!! [YTProbe] handleDocument("+document.URL+"): "+e+"\n");
  145.     }
  146. }
  147.  
  148. YTProbe.prototype.checkedYTHQ=function(url,args,format,extension) {
  149.     //dump("[YTProbe] checkedYTHQ("+url+",args)\n");
  150.     if(url) {
  151.         var desc=this.core.cloneEntry(args);
  152.         Util.setPropsString(desc,"media-url",url);
  153.         var document=desc.get("document",Components.interfaces.nsIDOMDocument);
  154.         var window=desc.get("window",Components.interfaces.nsIDOMWindow);
  155.         var fileName=Util.getPropsString(desc,"file-name");
  156.         Util.setPropsString(desc,"file-name",fileName+"."+extension);
  157.         Util.setPropsString(desc,"file-extension",extension);
  158.         Util.setPropsString(desc,"capture-method","youtube-hq");
  159.         var title=Util.getPropsString(desc,"youtube-title");
  160.         var prefix=Util.getFText("label.high-quality-prefix2",[""+format],1)+" ";
  161.         Util.setPropsString(desc,"label-prefix",prefix);
  162.         Util.setPropsString(desc,"label",prefix+title);
  163.         this.core.addEntryForDocument(desc,document,window);
  164.     }
  165. }
  166.  
  167. YTProbe.prototype.handleRequest=function(request) {
  168. }
  169.     
  170. YTProbe.prototype.handleResponse=function(request) {
  171. }
  172.     
  173. YTProbe.prototype.QueryInterface = function(iid) {
  174.     //dump("[YTProbe] QueryInterface("+iid+")\n");
  175.     if(
  176.         iid.equals(Components.interfaces.dhIProbe) ||
  177.         iid.equals(Components.interfaces.dhIYTHQCheckerListener) ||
  178.         iid.equals(Components.interfaces.nsISupports)
  179.     ) {
  180.         return this;
  181.     }
  182.     throw Components.results.NS_ERROR_NO_INTERFACE;
  183. }
  184.  
  185. var vYTProbeModule = {
  186.     firstTime: true,
  187.     
  188.     /*
  189.      * RegisterSelf is called at registration time (component installation
  190.      * or the only-until-release startup autoregistration) and is responsible
  191.      * for notifying the component manager of all components implemented in
  192.      * this module.  The fileSpec, location and type parameters are mostly
  193.      * opaque, and should be passed on to the registerComponent call
  194.      * unmolested.
  195.      */
  196.     registerSelf: function (compMgr, fileSpec, location, type) {
  197.  
  198.         if (this.firstTime) {
  199.             this.firstTime = false;
  200.             throw Components.results.NS_ERROR_FACTORY_REGISTER_AGAIN;
  201.         }
  202.         compMgr = compMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
  203.         compMgr.registerFactoryLocation(NS_YTPROBE_CID,
  204.                                         "YTProbe",
  205.                                         NS_YTPROBE_PROG_ID, 
  206.                                         fileSpec,
  207.                                         location,
  208.                                         type);
  209.     },
  210.  
  211.     unregisterSelf: function(compMgr, fileSpec, location) {
  212.         compMgr = compMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
  213.         compMgr.unregisterFactoryLocation(NS_DH_YTPROBE_CID, fileSpec);
  214.     },
  215.  
  216.     /*
  217.      * The GetClassObject method is responsible for producing Factory and
  218.      * SingletonFactory objects (the latter are specialized for services).
  219.      */
  220.     getClassObject: function (compMgr, cid, iid) {
  221.         if (!cid.equals(NS_YTPROBE_CID)) {
  222.             throw Components.results.NS_ERROR_NO_INTERFACE;
  223.         }
  224.  
  225.         if (!iid.equals(Components.interfaces.nsIFactory)) {
  226.             throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
  227.         }
  228.  
  229.         return this.vYTProbeFactory;
  230.     },
  231.  
  232.     /* factory object */
  233.     vYTProbeFactory: {
  234.         /*
  235.          * Construct an instance of the interface specified by iid, possibly
  236.          * aggregating it with the provided outer.  (If you don't know what
  237.          * aggregation is all about, you don't need to.  It reduces even the
  238.          * mightiest of XPCOM warriors to snivelling cowards.)
  239.          */
  240.         createInstance: function (outer, iid) {
  241.             if (outer != null) {
  242.                 throw Components.results.NS_ERROR_NO_AGGREGATION;
  243.             }
  244.     
  245.             if(Util==null) 
  246.                 Util=Components.classes["@downloadhelper.net/util-service;1"]
  247.                     .getService(Components.interfaces.dhIUtilService);
  248.  
  249.             return new YTProbe().QueryInterface(iid);
  250.         }
  251.     },
  252.  
  253.     /*
  254.      * The canUnload method signals that the component is about to be unloaded.
  255.      * C++ components can return false to indicate that they don't wish to be
  256.      * unloaded, but the return value from JS components' canUnload is ignored:
  257.      * mark-and-sweep will keep everything around until it's no longer in use,
  258.      * making unconditional ``unload'' safe.
  259.      *
  260.      * You still need to provide a (likely useless) canUnload method, though:
  261.      * it's part of the nsIModule interface contract, and the JS loader _will_
  262.      * call it.
  263.      */
  264.     canUnload: function(compMgr) {
  265.         return true;
  266.     }
  267. };
  268.  
  269. function NSGetModule(compMgr, fileSpec) {
  270.     return vYTProbeModule;
  271. }
  272.  
  273.